package com.candy.service.impl;

import com.candy.dao.AccountDao;

import com.candy.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.Date;

/**
 * 使用注解配置IOC
 * 作用等价于XML配置
 * 分析：
 * 使用XML配置的完整内容如下：
 * <bean id="accountDao" class="com.candy.dao.impl.AccountDaoImpl" scope="prototype"
 *     init-method="start" destroy-method="end">
 *      <property name="username" value="张三"></property>
 * </bean>
 * XML配置的功能主要分4种：
 * 1、bean：用于对象实例化(对应的注解有：@Component、@Controller、@Service、@Repository)
 * 2、property：依赖注入(@Value、@Autowired、@Qualifier、@Resource）
 * 3、scope：指定bean的作用范围 (@Scope)
 * 4、init-method、destroy：与生命周期相关的(@PostConstruct、@PreDestroy)
 */


/**
 * @Controller、@Service、@Repository
 * 他们三个注解都是针对一个的衍生注解，他们的作用及属性都是一模一样的。他们只不过是提供了更加明确的语义化。
 * @Controller：一般用于表现层的注解。
 * @Service：一般用于业务层的注解。
 * @Repository：一般用于持久层的注解。
 *
 * @Scope用于改变bean的作用范围的
 * value可以设置的值：singleton prototype request session globalsession
 */
@Service(value = "accountService")
//@Scope(value = "prototype")
public class AccountServiceImpl implements AccountService {
    /**
     * @Value注解:可以注入基本类型以及String类型的变量
     * 也可以注入bean类型的变量
     * 注入bean类型的变量时，需要使用#{}指定要注入bean的id
     */
    @Value("张三")
    private String username;
    @Value("22")
    private Integer age;
    @Value("#{new java.util.Date()}")
    private Date birthday;
    /**
     * @Autowired注解可以实现依赖注入，注入一个bean类型的变量 等价于property 中ref属性的作用
     * @Autowired是根据type（类型）进行注入，若找到多个匹配的对象，会报错，此时可以搭配Qualifier指定要注入的bean的id
     *
     * Resource根据bean的id进行注入
     */
//    @Autowired
//    @Qualifier("accountDaoImpl")
//    @Resource(name = "accountDaoImpl")
    @Value("#{accountDaoImpl}")
    private AccountDao accountDao;

    public AccountServiceImpl() {

    }

    public AccountServiceImpl(String username, Integer age, Date birthday) {
        this.username = username;
        this.age = age;
        this.birthday = birthday;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public AccountDao getAccountDao() {
        return accountDao;
    }

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }

    @Override
    public void save() {
        accountDao.saveAccount();
    }

    @Override
    public String toString() {
        return "AccountServiceImpl{" +
                "username='" + username + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +'}';
    }

    /**
     *@PostConstruct
     * 作用：
     * 用于指定初始化方法。
     * @PreDestroy
     * 作用：
     * 用于指定销毁方法
     */
    @PostConstruct
    public void start(){
        System.out.println("对象被初始化，调用start方法....");
    }
    @PreDestroy
    public void end(){
        System.out.println("对象被销毁，调用end方法....");
    }
}
